package LearnDataStructure.a_线性结构.列表.链表;

import LearnDataStructure.a_线性结构.列表.MyList;

import java.util.Arrays;
import java.util.List;

/**
 * @version: 1.0
 * @Author: wuqiu
 * @date: 2023-07-01 17:01
 * @description: LeetcodeLearnAlgorithm -> LearnDataStructure.a_线性结构.列表.链表
 */
public class MyLinkedListSingle<T> implements MyList<T> {
    private MyNode head;
    private MyNode last;
    private MyNode now;
    private int size = 0;
    @Override
    public void add(T element) {
        if (head == null) {//头节点为空，代表链表此时无节点
            head = new MyNode(element);//加入新结点，此时链表有了第一个节点
            last = head;
            now = head;
        } else {//否则链表此时有至少一个节点
            last.next = new MyNode(element);//则在尾部添加新节点
            last = last.next;
        }
        size++;
    }

    @Override
    public void delete(T element) {
        if (head == null) {
            return;
        }
        MyNode temp = head;
        MyNode pre = null;
        while (temp != null) {
            if (temp.data.equals(element)) {
                if (temp == head) {//删除首个
                    head = temp.next;
                    size--;
                } else if (temp.next == null) {//删除最后一个
                    pre.next = null;
                    size--;
                } else {//其他情况
                    pre.next = temp.next;
                    size--;
                }
                break;
            }
            pre = temp;
            temp = temp.next;
        }
    }

    @Override
    public void delete(int index) {//传入的是索引数值
        if (index < 0 || index >= size || head == null) {
            return;
        }
        int i = 0;
        MyNode temp = head;
        MyNode pre = null;
        while (temp != null) {
            if (i == index) {
                if (temp == head) {
                    head = temp.next;
                    size--;
                } else if (temp.next == null) {
                    pre.next = null;
                    size--;
                } else {
                    pre.next = temp.next;
                    size--;
                }
                break;
            }
            pre = temp;
            temp = temp.next;
            i++;
        }
    }

    @Override
    public void update(int index, T newElement) {//传入的是索引数值
        if (index < 0 || index >= size || head == null) {
            return;
        }
        int i = 0;
        MyNode temp = head;
        while (temp != null) {
            if (i == index) {
                temp.data = newElement;
                break;
            }
            temp = temp.next;
            i++;
        }
    }

    @Override
    public boolean contains(T target) {
        if (head != null) {
            MyNode temp = head;
            while (temp != null) {
                if (temp.data.equals(target)) {
                    return true;
                }
                temp = temp.next;
            }
        }
        return false;
    }

    @Override
    public T AtElement(int index) {
        if (index < 0 || index >= size || head == null) {
            return null;
        }
        int i = 0;
        MyNode temp = head;
        while (temp != null) {
            if (i == index) {
                return (T)temp.data;
            }
            temp = temp.next;
            i++;
        }
        return null;
    }

    @Override
    public int indexOf(T element) {
        if (head != null) {
            int i = 0;
            MyNode temp = head;
            while (temp != null) {
                if (temp.data.equals(element)) {
                    return i;
                }
                temp = temp.next;
                i++;
            }
        }
        return -1;
    }


    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder("[");
        MyNode temp = head;
        while (temp.next != null) {
            stringBuilder.append(temp.data).append(" , ");
            temp = temp.next;
        }
        stringBuilder.append(temp.data).append("]").append(" size = " + size);
        return stringBuilder.toString();
    }

    @Override
    public boolean hasNext() {
        if (head == null) {
            return false;
        }
        if (now == head && head == last) {
            return true;
        }
        return now != null;
    }

    @Override
    public T next() {
        MyNode next = now;
        now = now.next;
        return (T)next.data;
    }
}
